import React, { useEffect, useMemo, useRef } from "react";
import MDEditor, { commands } from "@uiw/react-md-editor";
import "@uiw/react-md-editor/markdown-editor.css";
import "@uiw/react-markdown-preview/markdown.css";

interface IProps {
  customUpload?: (file: File, insertFn: (url: string) => void) => void;
  onChange?: (markdown?: string) => void;
  value?: string;
  placeholder?: string;
  height?: number;
  theme?: "light" | "dark";
}

function MarkEditor(props: IProps) {
  const [value, setValue] = React.useState<string | undefined>(props.value);
  const editorRef = useRef(null);

  const onChange = (value?: string) => {
    setValue(value);
    props.onChange?.(value);
  };

  const imageUploadCommand = (state: any, api: any) => {
    const input = document.createElement("input");
    input.type = "file";
    input.accept = "image/*";
    input.onchange = (e: any) => {
      const file = e.target.files[0];
      if (!file) return;

      const insertImage = (url: string) => {
        api.replaceSelection(`![${file.name}](${url})`);
      };

      if (props.customUpload) {
        props.customUpload(file, insertImage);
      }
    };
    input.click();
  };

  const handlePaste = async (e: React.ClipboardEvent) => {
    const items = e.clipboardData.items;
    let isImagePasted = false;

    for (let i = 0; i < items.length; i++) {
      const item = items[i];
      if (item.type.indexOf("image") !== -1) {
        isImagePasted = true;
        await pasteImg(e, item.getAsFile());
        break;
      }
    }

    if (!isImagePasted) {
      const pasteText = e.clipboardData.getData("text/plain");
      const cursorPosition = (e.target as any).selectionStart as number;
      if (value) {
        const newValue =
          value.substring(0, cursorPosition) +
          pasteText +
          value.substring(cursorPosition);
        setValue(newValue);
      }
    }
  };

  const pasteImg = async (event: React.ClipboardEvent, file: File | null) => {
    if (!file) return;
    
    event.preventDefault();
    const placeholder = `![Uploading ${file.name}...]()`;
    const cursorPosition = (event.target as any).selectionStart as number;
    if (value) {
      const newValue =
        value.substring(0, cursorPosition) +
        placeholder +
        value.substring(cursorPosition);
      setValue(newValue);
    }

    const insertImage = (url: string) => {
      setValue((prevValue) =>
        prevValue?.replace(placeholder, `![${file.name}](${url})`)
      );
    };

    if (props.customUpload) {
      props.customUpload(file, insertImage);
    }
  };

  const newCommands = useMemo(() => {
    return commands.getCommands().map((item) => {
      if (item.name === "image") {
        item.execute = imageUploadCommand;
      }
      return item;
    });
  }, []);

  useEffect(() => {
    setValue(props.value);
  }, [props.value]);

  return (
    <div data-color-mode={props?.theme ?? "light"}>
      {React.createElement(MDEditor as any, {
        ref: editorRef,
        height: props.height ?? 500,
        value: value,
        onChange: onChange,
        commands: newCommands,
        onPaste: handlePaste
      })}
    </div>
  );
}

export default MarkEditor;
